package com.sun.springbootfiledownload.service;

import com.sun.springbootfiledownload.result.AliyunOssResult;
import com.sun.springbootfiledownload.utils.AliyunOssPlusUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;

/**
 * @version 1.0
 * @Package: com.sun.springbootfiledownload.service
 * @ClassName: FileAsyncService
 * @Author: sgq
 * @Date: 2025/4/10 14:25
 * @Description: TODD
 */
@Slf4j
@Service
public class FileAsyncService {

    @Autowired
    private AliyunOssPlusUtil aliyunOSSUtil;

    /**
     * 异步上传文件到OSS
     * @param file 上传的文件
     * @param folder 上传到的文件夹
     * @return 包含文件URL的CompletableFuture
     */
    @Async("fileTaskExecutor")
    public CompletableFuture<AliyunOssResult> asyncUpload(MultipartFile file, String folder) {
        try {
            log.info("开始异步上传文件: {}", file.getOriginalFilename());
            AliyunOssResult upload = aliyunOSSUtil.uploadTemp(file, folder);
            return CompletableFuture.completedFuture(upload);
        } catch (Exception e) {
            log.error("异步上传文件失败", e);
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 完全避免临时文件问题的异步上传方法
     */
    @Async("fileTaskExecutor")
    public CompletableFuture<String> absolutelySafeUpload(MultipartFile file, String folder) {
        // 立即将文件内容读取到内存（关键步骤）
        byte[] fileBytes;
        try {
            fileBytes = file.getBytes();
            log.info("文件已加载到内存，大小: {}KB", fileBytes.length / 1024);
        } catch (IOException e) {
            log.error("文件读取失败: {}", file.getOriginalFilename(), e);
            return CompletableFuture.failedFuture(e);
        }

        // 获取原始文件名（必须在异步方法内获取）
        String originalFilename = file.getOriginalFilename();

        try {
            String url = aliyunOSSUtil.safeUpload(fileBytes, originalFilename, folder);
            return CompletableFuture.completedFuture(url);
        } catch (Exception e) {
            log.error("异步上传失败: {}", originalFilename, e);
            return CompletableFuture.failedFuture(e);
        }
    }

    // 在SafeAsyncUploadService中添加
    @Async
    public CompletableFuture<String> uploadLargeFile(MultipartFile file, String folder) throws IOException {
        // 使用临时文件（需确保不会被删除）
        File tempFile = null;
        try {
            tempFile = File.createTempFile("oss-upload-", ".tmp");
            file.transferTo(tempFile);

            // 使用OSS的分片上传API
            String url = aliyunOSSUtil.uploadLargeFile(tempFile, folder);
            return CompletableFuture.completedFuture(url);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete(); // 清理临时文件
            }
        }
    }

    /**
     * 异步从OSS下载文件
     * @param filePath OSS中的文件路径
     * @return 包含文件内容的CompletableFuture
     */
    @Async("fileTaskExecutor")
    public CompletableFuture<byte[]> asyncDownload(String filePath) {
        try {
            log.info("开始异步下载文件: {}", filePath);
            InputStream download = aliyunOSSUtil.download(filePath);
            byte[] fileContent = download.readAllBytes();
            return CompletableFuture.completedFuture(fileContent);
        } catch (Exception e) {
            log.error("异步下载文件失败", e);
            return CompletableFuture.failedFuture(e);
        }
    }
}